home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / exampleCode / opengl / xlib / cull.c < prev    next >
C/C++ Source or Header  |  1996-11-11  |  11KB  |  400 lines

  1. /*
  2.  * (c) Copyright 1993-94, Silicon Graphics, Inc.
  3.  * ALL RIGHTS RESERVED
  4.  *
  5.  * Permission to use, copy, modify, and distribute this software for
  6.  * any purpose and without fee is hereby granted, provided that the above
  7.  * copyright notice appear in all copies and that both the copyright notice
  8.  * and this permission notice appear in supporting documentation, and that
  9.  * the name of Silicon Graphics, Inc. not be used in advertising
  10.  * or publicity pertaining to distribution of the software without specific,
  11.  * written prior permission.
  12.  *
  13.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  14.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  15.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  16.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  17.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  18.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  19.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  20.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  21.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  22.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  23.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  24.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  25.  *
  26.  * U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND
  27.  * Use, duplication, or disclosure by the Government is subject to
  28.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  29.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  30.  * clause at DFARS 252.227-7013 and/or in similar or successor
  31.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  32.  * Unpublished-- rights reserved under the copyright laws of the
  33.  * United States.  Contractor/manufacturer is Silicon Graphics,
  34.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  35.  *
  36.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  37.  */
  38. #include <GL/glx.h>
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <X11/keysym.h>
  42.  
  43. static int attributes[] = {
  44.     GLX_RGBA,
  45.     GLX_RED_SIZE, 1,
  46.     GLX_GREEN_SIZE, 1,
  47.     GLX_BLUE_SIZE, 1,
  48.     None,
  49. };
  50.  
  51. int width = 350, height = 450;
  52.  
  53. static GLfloat cwa[2] = { 0, -1 };
  54. static GLfloat cwb[2] = { -1, .5 };
  55. static GLfloat cwc[2] = { 1, 1 };
  56. static GLfloat ccwa[2] = { 0, -1 };
  57. static GLfloat ccwb[2] = { 1, .5 };
  58. static GLfloat ccwc[2] = { -1, 1 };
  59.  
  60. static GLfloat ca[3] = { 1, 0, 0 };
  61. static GLfloat cb[3] = { 0, 1, 0 };
  62. static GLfloat cc[3] = { 0, 0, 1 };
  63.  
  64. static GLubyte ZeroBitmap[9] = {
  65.     0x1c, 0x22, 0x22, 0x32, 0x2a, 0x26, 0x22, 0x22, 0x1c,
  66. };
  67.  
  68. static GLubyte OneBitmap[9] = {
  69.     0x0e, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x0c, 0x04,
  70. };
  71.  
  72. static GLubyte TwoBitmap[9] = {
  73.     0x3e, 0x20, 0x10, 0x08, 0x04, 0x02, 0x22, 0x22, 0x1c,
  74. };
  75.  
  76. static void Label(GLfloat first[2], GLfloat second[2], GLfloat third[2])
  77. {
  78.     glColor3f(1, 1, 1);
  79.     glRasterPos2fv(first);
  80.     glBitmap(8, 9, 0, 0, 0, 0, ZeroBitmap);
  81.     glRasterPos2fv(second);
  82.     glBitmap(8, 9, 0, 0, 0, 0, OneBitmap);
  83.     glRasterPos2fv(third);
  84.     glBitmap(8, 9, 0, 0, 0, 0, TwoBitmap);
  85. }
  86.  
  87. static void DrawTriangles(void)
  88. {
  89.     glPushMatrix();
  90.  
  91.     Label(cwa, cwb, cwc);
  92.     glBegin(GL_TRIANGLES);
  93.     glColor3fv(ca); glVertex2fv(cwa); 
  94.     glColor3fv(cb); glVertex2fv(cwb);
  95.     glColor3fv(cc); glVertex2fv(cwc);
  96.     glEnd();
  97.     glTranslatef(3.5, 0, 0);
  98.     Label(ccwa, ccwb, ccwc);
  99.     glBegin(GL_TRIANGLES);
  100.     glColor3fv(ca); glVertex2fv(ccwa);
  101.     glColor3fv(cb); glVertex2fv(ccwb);
  102.     glColor3fv(cc); glVertex2fv(ccwc);
  103.     glEnd();
  104.  
  105.     glTranslatef(-3.5, 3.5, 0);
  106.     Label(cwa, cwc, cwb);
  107.     glBegin(GL_TRIANGLES);
  108.     glColor3fv(ca); glVertex2fv(cwa);
  109.     glColor3fv(cc); glVertex2fv(cwc);
  110.     glColor3fv(cb); glVertex2fv(cwb);
  111.     glEnd();
  112.     glTranslatef(3.5, 0, 0);
  113.     Label(ccwa, ccwc, ccwb);
  114.     glBegin(GL_TRIANGLES);
  115.     glColor3fv(ca); glVertex2fv(ccwa);
  116.     glColor3fv(cc); glVertex2fv(ccwc);
  117.     glColor3fv(cb); glVertex2fv(ccwb);
  118.     glEnd();
  119.  
  120.     glTranslatef(-3.5, 3.5, 0);
  121.     Label(cwb, cwa, cwc);
  122.     glBegin(GL_TRIANGLES);
  123.     glColor3fv(cb); glVertex2fv(cwb);
  124.     glColor3fv(ca); glVertex2fv(cwa);
  125.     glColor3fv(cc); glVertex2fv(cwc);
  126.     glEnd();
  127.     glTranslatef(3.5, 0, 0);
  128.     Label(ccwb, ccwa, ccwc);
  129.     glBegin(GL_TRIANGLES);
  130.     glColor3fv(cb); glVertex2fv(ccwb);
  131.     glColor3fv(ca); glVertex2fv(ccwa);
  132.     glColor3fv(cc); glVertex2fv(ccwc);
  133.     glEnd();
  134.  
  135.     glTranslatef(-3.5, 3.5, 0);
  136.     Label(cwb, cwc, cwa);
  137.     glBegin(GL_TRIANGLES);
  138.     glColor3fv(cb); glVertex2fv(cwb);
  139.     glColor3fv(cc); glVertex2fv(cwc);
  140.     glColor3fv(ca); glVertex2fv(cwa);
  141.     glEnd();
  142.     glTranslatef(3.5, 0, 0);
  143.     Label(ccwb, ccwc, ccwa);
  144.     glBegin(GL_TRIANGLES);
  145.     glColor3fv(cb); glVertex2fv(ccwb);
  146.     glColor3fv(cc); glVertex2fv(ccwc);
  147.     glColor3fv(ca); glVertex2fv(ccwa);
  148.     glEnd();
  149.  
  150.     glTranslatef(-3.5, 3.5, 0);
  151.     Label(cwc, cwa, cwb);
  152.     glBegin(GL_TRIANGLES);
  153.     glColor3fv(cc); glVertex2fv(cwc);
  154.     glColor3fv(ca); glVertex2fv(cwa);
  155.     glColor3fv(cb); glVertex2fv(cwb);
  156.     glEnd();
  157.     glTranslatef(3.5, 0, 0);
  158.     Label(ccwc, ccwa, ccwb);
  159.     glBegin(GL_TRIANGLES);
  160.     glColor3fv(cc); glVertex2fv(ccwc);
  161.     glColor3fv(ca); glVertex2fv(ccwa);
  162.     glColor3fv(cb); glVertex2fv(ccwb);
  163.     glEnd();
  164.  
  165.     glTranslatef(-3.5, 3.5, 0);
  166.     Label(cwc, cwb, cwa);
  167.     glBegin(GL_TRIANGLES);
  168.     glColor3fv(cc); glVertex2fv(cwc);
  169.     glColor3fv(cb); glVertex2fv(cwb);
  170.     glColor3fv(ca); glVertex2fv(cwa);
  171.     glEnd();
  172.     glTranslatef(3.5, 0, 0);
  173.     Label(ccwc, ccwb, ccwa);
  174.     glBegin(GL_TRIANGLES);
  175.     glColor3fv(cc); glVertex2fv(ccwc);
  176.     glColor3fv(cb); glVertex2fv(ccwb);
  177.     glColor3fv(ca); glVertex2fv(ccwa);
  178.     glEnd();
  179.  
  180.     glPopMatrix();
  181. }
  182.  
  183. static void DoDisplay(void)
  184. {
  185.     glMatrixMode(GL_PROJECTION);
  186.     glLoadIdentity();
  187.     glOrtho(-0.5, width - 0.5, -0.5, height - 0.5, 0.01, 1000.0);
  188.     glMatrixMode(GL_MODELVIEW);
  189.     glLoadIdentity();
  190.  
  191.     glViewport(0, 0, width, height);
  192.     glClearColor(0.25, 0.25, 0.25, 1.0);
  193.     glClear(GL_COLOR_BUFFER_BIT);
  194.  
  195.     /* Draw flat triangles */
  196.     glShadeModel(GL_FLAT);
  197.     glTranslatef(50, 50, -10);
  198.     glScalef(20, 20, 1);
  199.     DrawTriangles();
  200.  
  201.     /* Draw smooth triangles */
  202.     glShadeModel(GL_SMOOTH);
  203.     glTranslatef(8, 0, 0);
  204.     DrawTriangles();
  205. }
  206.  
  207. static Bool WaitForMapNotify(Display *d, XEvent *e, char *arg)
  208. {
  209.     if ((e->type == MapNotify) && (e->xmap.window == (Window)arg)) {
  210.     return GL_TRUE;
  211.     }
  212.     return GL_FALSE;
  213. }
  214.  
  215. static const char* FaceName(GLenum face)
  216. {
  217.     switch (face) {
  218.       case GL_FRONT:        return "front";
  219.       case GL_BACK:        return "back";
  220.       case GL_FRONT_AND_BACK:    return "front and back";
  221.       default:            return "???";
  222.     }
  223. }
  224.  
  225. static const char* PolygonMode(GLenum mode)
  226. {
  227.     switch (mode) {
  228.       case GL_FILL:        return "fill";
  229.       case GL_POINT:        return "point";
  230.       case GL_LINE:        return "line";
  231.       default:            return "???";
  232.     }
  233. }
  234.  
  235. static const char* FrontFaceName(GLenum mode)
  236. {
  237.     switch (mode) {
  238.       case GL_CW:        return "CW";
  239.       case GL_CCW:        return "CCW";
  240.       default:            return "???";
  241.     }
  242. }
  243.  
  244. static void DisplayState(void)
  245. {
  246.     GLint frontFace, cullFace, polygonMode[2];
  247.     GLboolean cullEnabled;
  248.  
  249.     glGetIntegerv(GL_FRONT_FACE, &frontFace);
  250.     glGetIntegerv(GL_CULL_FACE_MODE, &cullFace);
  251.     glGetIntegerv(GL_POLYGON_MODE, &polygonMode[0]);
  252.     cullEnabled = glIsEnabled(GL_CULL_FACE);
  253.  
  254.     printf("PolygonMode: front=%s back=%s\n",
  255.        PolygonMode(polygonMode[0]),
  256.        PolygonMode(polygonMode[1]));
  257.     printf("CullFace: %s (%s)\n", FaceName(cullFace),
  258.        cullEnabled ? "enabled" : "disabled");
  259.     printf("FrontFace: %s\n", FrontFaceName(frontFace));
  260.     printf("\n");
  261. }
  262.  
  263. int main()
  264. {
  265.     XVisualInfo *vi;
  266.     Display *dpy;
  267.     Colormap cmap;
  268.     Window window;
  269.     XSetWindowAttributes swa;
  270.     GLXContext cx;
  271.     XEvent event;
  272.     GLboolean needDisplay;
  273.     GLint ccw, cull;
  274.     GLenum face;
  275.  
  276.     dpy = XOpenDisplay(0);
  277.     if (!dpy) {
  278.     fprintf(stderr, "Can't connect to display \"%s\"\n", getenv("DISPLAY"));
  279.     return -1;
  280.     }
  281.  
  282.     vi = glXChooseVisual(dpy, DefaultScreen(dpy), attributes);
  283.     if (!vi) {
  284.     fprintf(stderr, "No singlebuffered rgba visual on \"%s\"\n",
  285.         getenv("DISPLAY"));
  286.     return -1;
  287.     }
  288.  
  289.     cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual,
  290.                AllocNone);
  291.     swa.border_pixel = 0;
  292.     swa.colormap = cmap;
  293.     swa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask
  294.     | KeyReleaseMask;
  295.     window = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 10, 10,
  296.                width, height,
  297.                0, vi->depth, InputOutput, vi->visual,
  298.                CWBorderPixel|CWColormap|CWEventMask, &swa);
  299.     XSetWMColormapWindows(dpy, window, &window, 1);
  300.     XStoreName(dpy, window, "Culling test");
  301.     XMapWindow(dpy, window);
  302.     XIfEvent(dpy, &event, WaitForMapNotify, (char*)window);
  303.  
  304.     cx = glXCreateContext(dpy, vi, 0, GL_TRUE);
  305.     if (!glXMakeCurrent(dpy, window, cx)) {
  306.     fprintf(stderr, "Can't make window current to context\n");
  307.     return -1;
  308.     }
  309.  
  310.     face = GL_FRONT_AND_BACK;
  311.     ccw = 0;
  312.     cull = 0;
  313.     glPolygonMode(face, GL_FILL);
  314.     glFrontFace(GL_CW);
  315.     glCullFace(GL_FRONT);
  316.     glDisable(GL_CULL_FACE);
  317.     DisplayState();
  318.  
  319.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  320.     glPointSize(4.0);
  321.     glEnable(GL_POINT_SMOOTH);
  322.  
  323.     needDisplay = GL_TRUE;
  324.     for (;;) {
  325.     do {
  326.         XNextEvent(dpy, &event);
  327.         switch (event.type) {
  328.           case Expose:
  329.         needDisplay = GL_TRUE;
  330.         break;
  331.           case ConfigureNotify:
  332.         width = event.xconfigure.width;
  333.         height = event.xconfigure.height;
  334.         needDisplay = GL_TRUE;
  335.         break;
  336.           case KeyPress:
  337.         {
  338.             char buf[100];
  339.             int rv;
  340.             KeySym ks;
  341.  
  342.             rv = XLookupString(&event.xkey, buf, sizeof(buf), &ks, 0);
  343.             switch (ks) {
  344.               case XK_0: face = GL_FRONT; break;
  345.               case XK_1: face = GL_BACK; break;
  346.               case XK_2: face = GL_FRONT_AND_BACK; break;
  347.               case XK_p:
  348.               case XK_P:
  349.             glPolygonMode(face, GL_POINT);
  350.             needDisplay = GL_TRUE;
  351.             break;
  352.               case XK_l:
  353.               case XK_L:
  354.             glPolygonMode(face, GL_LINE);
  355.             needDisplay = GL_TRUE;
  356.             break;
  357.               case XK_f:
  358.               case XK_F:
  359.             glPolygonMode(face, GL_FILL);
  360.             needDisplay = GL_TRUE;
  361.             break;
  362.               case XK_d:
  363.               case XK_D:
  364.             ccw = !ccw;
  365.             glFrontFace(ccw ? GL_CCW : GL_CW);
  366.             needDisplay = GL_TRUE;
  367.             break;
  368.               case XK_c:
  369.               case XK_C:
  370.             if (face != GL_FRONT_AND_BACK) {
  371.                 glCullFace(face);
  372.                 needDisplay = GL_TRUE;
  373.             }
  374.             break;
  375.               case XK_e:
  376.               case XK_E:
  377.             cull = !cull;
  378.             if (cull) {
  379.                 glEnable(GL_CULL_FACE);
  380.             } else {
  381.                 glDisable(GL_CULL_FACE);
  382.             }
  383.             needDisplay = GL_TRUE;
  384.             break;
  385.               case XK_Escape:
  386.             return 0;
  387.             }
  388.         }
  389.         break;
  390.         }
  391.     } while (XPending(dpy) != 0);
  392.  
  393.     if (needDisplay) {
  394.         needDisplay = GL_FALSE;
  395.         DisplayState();
  396.         DoDisplay();
  397.     }
  398.     }
  399. }
  400.